package com.ug_project.adapters

import android.app.Activity
import android.content.Context
import android.util.SparseIntArray
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.module.LoadMoreModule

import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.ug_project.objects.isNull
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
 * Created by yeganaaa on 3/7/2017.
 */

class RecyclerAdapter<T>(
    var defaultlayout_resID: Int,
    var datas: ArrayList<T>
) : BaseQuickAdapter<T, BaseViewHolder>(defaultlayout_resID, datas), LoadMoreModule {

    var basedata = ArrayList<T>()
    private var _OnBindViewHolder: ((itemview: View, itemViewResID: Int, data: ArrayList<T>, position: Int) -> Unit)? =
        null
    private var _OnBindViewHolderForItemData: ((view: View, itemViewResID: Int, data: T, position: Int) -> Unit)? =
        null
    private var _OnViewRecycled: ((BaseViewHolder) -> Unit) = {}
    private var _inflater: LayoutInflater? = null


    init {
        animationEnable = true
        basedata.addAll(datas)
    }

    open fun addHeader(layoutRedId: Int, action: (view: View) -> View) {
        _inflater.isNull {
            _inflater = LayoutInflater.from(context)
        }
        val headerView = _inflater?.inflate(layoutRedId, null, false)
        addHeaderView(action(headerView!!))
    }

    open fun addFooter(layoutRedId: Int, action: (view: View) -> View) {
        _inflater.isNull {
            _inflater = LayoutInflater.from(context)
        }
        val footerView = _inflater?.inflate(layoutRedId, null, false)

        addFooterView(action(footerView!!))
    }

    fun filter(action: (T) -> Boolean) {
        datas.clear()
        datas.addAll(basedata.filter { action(it) })
        notifyDataSetChanged()
    }

    open fun OnBindViewHolder(binder: (rootView: View, itemViewResID: Int, data: ArrayList<T>, position: Int) -> Unit) {
        _OnBindViewHolder = binder
    }

    /**
     * On Bind View Holder For Item Data
     */
    open fun OnBindViewHolderIData(binder: (view: View, itemViewResID: Int, data: T, position: Int) -> Unit) {
        _OnBindViewHolderForItemData = binder
    }

    override fun convert(holder: BaseViewHolder, item: T) {
        if (layouts.size() <= 0) {
            _OnBindViewHolderForItemData?.invoke(
                holder.itemView,
                defaultlayout_resID,
                item,
                holder.adapterPosition
            )
        } else {
            _OnBindViewIType(holder.itemView, holder.itemViewType, item, holder.adapterPosition)
        }

    }


    //********************* MultiViewType ********************

    private val layouts: SparseIntArray by lazy(LazyThreadSafetyMode.NONE) { SparseIntArray() }

    internal var _OnBindViewIType: (View, Int, T, Int) -> Unit = { a, b, c, d -> }
    fun OnBindViewIType(
        action: (view: View, viewType: Int, data: T, position: Int) -> Unit
    ) {
        _OnBindViewIType = action
    }


    fun addViewType(type: Int, layoutId: Int) {
        layouts.put(type, layoutId)
    }

    internal var _GetItemViewType: (Int) -> Int = { 0 }
    fun GetItemViewType(action: (pos: Int) -> Int) {
        _GetItemViewType = action
    }

    override fun getDefItemViewType(position: Int): Int {
        return _GetItemViewType(position)
    }

    override fun onCreateDefViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        if (layouts.size() <= 0) {
            return super.onCreateDefViewHolder(parent, viewType)
        } else {
            return super.createBaseViewHolder(parent, layouts.get(viewType))
        }
    }


    //********************* Recycled ********************
    override fun onViewRecycled(holder: BaseViewHolder) {
        super.onViewRecycled(holder)
        _OnViewRecycled.invoke(holder)
    }

    open fun onViewRecycled(action: (BaseViewHolder) -> Unit) {
        _OnViewRecycled = action
    }

    //********************* LoadMore ********************
    open fun onLoadingMore(action: () -> Unit) {
        if (!loadMoreModule.isEnableLoadMore) {
            loadMoreModule.isEnableLoadMore= true
        }
        loadMoreModule.setOnLoadMoreListener {
            action()
        }
    }

    open fun loadingMoreComplete() {
        loadMoreModule.loadMoreComplete()
    }

    open fun loadingMoreEnd(gone: Boolean) {
        loadMoreModule.loadMoreEnd(gone)
    }

    open fun loadingMoreFail() {
        loadMoreModule.loadMoreFail()
    }

    open fun loadingMore() {
        loadMoreModule.loadMoreToLoading()
    }


    fun refresh() {
        basedata.clear()
        basedata.addAll(datas)
        notifyDataSetChanged()
    }


}

fun <T> createRecyclerAdapter(
    layoutId: Int, data: ArrayList<T>,
    creator: RecyclerAdapter<T>.() -> Unit
): RecyclerAdapter<T> {
    val adapter = RecyclerAdapter(layoutId, data)
    adapter.creator()
    return adapter
}

@Deprecated("use createRecyclerAdapter(layoutId,action)")
fun <T> createRecyclerAdapter(
    context: Context?, defaultlayout_resID: Int, data: ArrayList<T>,
    creator: RecyclerAdapter<T>.() -> Unit
): RecyclerAdapter<T> {
    val adapter = RecyclerAdapter<T>(defaultlayout_resID, data)
    adapter.creator()
    return adapter
}

//@Deprecated("use createRecyclerAdapter(layoutId,action)")
//fun <T> Activity.createRecyclerAdapter(
//    defaultlayout_resID: Int, data: ArrayList<T>,
//    creator: RecyclerAdapter<T>.() -> Unit
//): RecyclerAdapter<T> {
//    return createRecyclerAdapter(this, defaultlayout_resID, data, creator)
//}

//@Deprecated("use createRecyclerAdapter(layoutId,action)")
//fun <T> Fragment.createRecyclerAdapter(
//    defaultlayout_resID: Int, data: ArrayList<T>,
//    creator: RecyclerAdapter<T>.() -> Unit
//): RecyclerAdapter<T> {
//    return createRecyclerAdapter(context, defaultlayout_resID, data, creator)
//}


